const fs = require('fs');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const path = require('path');
const babel = require('@babel/core');

const getModuleInfo = (file) => {
    const body = fs.readFileSync(file, 'utf-8');
    const ast = parser.parse(body, {
        sourceType: 'module'//告诉 babel 我们的代码是 ES 模块
    })
    const deps = {

    };
    traverse(ast, {
        ImportDeclaration({ node }) {
            const dirname = path.dirname(file);
            const abspath = './' + path.join(dirname, node.source.value);
            // console.log(abspath);
            deps[node.source.value] = abspath;

        }
    })
    // console.log(ast);
    //根据ast生成低版本的js代码
    const { code } = babel.transformFromAst(ast, null, {
        presets: ['@babel/preset-env']
    })
    const moduleInfo = {
        file,
        deps,
        code
    }
    return moduleInfo;


}
const parseModules = (file) => {
    const entry = getModuleInfo(file);
    const temp = [entry]
    for (let i = 0; i < temp.length; i++) {
        const deps = temp[i].deps
        console.log(deps);
        for (const key in deps) {
            if (deps.hasOwnProperty(key)) {
                const child = deps[key];
                temp.push(getModuleInfo(child));
            }
        }
    }
    const depsGraph = {};
    temp.forEach(item => {
        depsGraph[item.file] = {
            deps: item.deps,
            code: item.code
        }
    })
    return depsGraph;
}
//处理一下require和exports对象
const bundle = (file) => {
    const depsGraph = JSON.stringify(parseModules(file));
    return `(function(graph) {
            function require(file) {

              function absRequire(relPath) {
                return require(graph[file].deps[relPath])
              }

              var exports = {};

              (function(require, exports, code) {
                eval(code)
              })(absRequire, exports, graph[file].code);
              
              return exports
            }
            require("${file}");

          })(${depsGraph});`
}
const code = bundle('./src/index.js');
fs.mkdirSync('./dist')
fs.writeFileSync('./dist/bundle.js', code);

